<?php
/**
 *    Copyright 2010 Show Framework(www.showframework.cn)
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 * 
 *        http://www.apache.org/licenses/LICENSE-2.0
 * 
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 * Show_Db_Handle_Mysqli
 * 使用Mysqli底层函数实现的数据库驱动
 * 
 * @package Show_Db_Handle
 * @name Show_Db_Handle_Mysqli
 * @author show
 * @since v0.6
 */
class Show_Db_Handle_Mysqli extends mysqli implements Show_Db_Handle_Interface
{
    /**
     * @var MySQLi_Result
     */
    protected $queryResult;
    
    /**
     * @var bool
     */
    protected $lastQueryOk;
    
    /**
     * Show_Db_Handle_Mysqli
     *
     * @param string $host
     * @param string $user
     * @param string $pass
     * @param string $db
     * @return Show_Db_Handle_Interface
     */
    public function __construct($host, $user, $pass, $db = null)
    {
        $this->lastQueryOk = false;
        parent::init();
        if (!parent::real_connect($host, $user, $pass, $db)) {
            trigger_error(mysqli_connect_error(), E_USER_ERROR);
        }
    }
    
    /**
     * Get number of affected rows in previous MySQL operation
     * Returns the number of rows affected by the last INSERT, UPDATE, REPLACE or DELETE query.
     * > 0 
     * 0 no records affected
     * -1 error
     * 
     * @return int
     */
    public function affected()
    {
        return $this->affected_rows;
    }
    
    /**
     * Move internal result pointer
     * Returns TRUE on success or FALSE on failure. 
     *
     * @param int $offset
     * @return bool
     */
    public function seek($offset)
    {
        return $this->queryResult->data_seek($offset);
    }
    
    /**
     * Returns the numerical value of the error message from previous MySQL operation
     * zero means no error occurred.
     *
     * @return int
     */
    public function errno()
    {
        return $this->errno;
    }
    
    /**
     * Returns the text of the error message from previous MySQL operation
     * An empty string if no error occurred.
     *
     * @return string
     */
    public function error()
    {
        return $this->error;
    }
    
    /**
     * Fetch a result row as an associative array, a numeric array, or both or object
     * 
     * @param int $fetchMode
     * @return array|object|false
     */
    public function fetch($fetchMode = Show_DB::FETCH_ASSOC)
    {
        return $this->lastQueryOk ? ($fetchMode === Show_Db::FETCH_OBJ ? $this->queryResult->fetch_object() : $this->queryResult->fetch_array($fetchMode)) : false;
    }
    
    /**
     * Frees the memory associated with a result
     * 
     * @return bool
     */
    public function free()
    {
        $this->queryResult->free();
        return true;
    }
    
    /**
     * Get the ID generated from the previous INSERT operation
     * Retrieves the ID generated for an AUTO_INCREMENT column by the previous INSERT query.
     *
     * @return int
     */
    public function insertId()
    {
        return $this->insert_id;
    }
    
    /**
     * Gets the number of rows in a result
     *
     * @return int
     */
    public function rows()
    {
        return $this->lastQueryOk ? $this->queryResult->num_rows : 0;
    }
    
    /**
     * Send a MySQL query
     * 通用查询 执行任何SQL语句
     *
     * @param string $sql
     * @return bool
     */
    public function query($sql)
    {
        $this->lastQueryOk = false;
        if (($this->queryResult = parent::query($sql)) !== false) {
            $this->lastQueryOk = true;
        }
        return $this->lastQueryOk;
    }
    
    /**
     * Escapes special characters in a string for use in a SQL statement
     * 转义特殊字符
     *
     * @param string $string
     * @return string
     */
    public function escape($string)
    {
        return $this->real_escape_string($string);
    }
    
    /**
     * 选择活动的数据库
     *
     * @param string $name
     * @return bool
     */
    public function db($name)
    {
        return $this->select_db($name);
    }
    
    /**
     * Sets the client character set
     *
     * @param string $charset
     * @return bool
     */
    public function charset($charset)
    {
        return $this->set_charset($charset);
    }
}
?>